package com.hyfd.service.mp;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.hyfd.common.utils.DateTimeUtils;
import com.hyfd.common.utils.MapUtils;
import com.hyfd.dao.mp.AgentAccountChargeDao;
import com.hyfd.dao.mp.AgentAccountDao;
import com.hyfd.dao.mp.AgentBillDiscountDao;
import com.hyfd.dao.mp.AgentDao;
import com.hyfd.dao.mp.BaseBillDiscountDetailDao;
import com.hyfd.dao.mp.BillPkgDao;
import com.hyfd.dao.mp.OrderDao;
import com.hyfd.dao.mp.PhoneSectionDao;
import com.hyfd.dao.mp.ProviderBillDiscountDao;
import com.hyfd.dao.mp.ProviderBillDispatcherDao;
import com.hyfd.dao.mp.ProviderBillRechargeGroupDao;
import com.hyfd.dao.mp.ProviderGroupBillRelDao;
import com.hyfd.dao.mp.ProviderPhysicalChannelDao;
import com.hyfd.rabbitMq.RabbitMqProducer;
import com.hyfd.rabbitMq.SerializeUtil;
import com.hyfd.service.BaseService;

@Service
public class RechargeBillSer extends BaseService
{
    
    public Logger log = Logger.getLogger(this.getClass());
    
    @Autowired
    AgentDao agentDao;// 代理商
    
    @Autowired
    PhoneSectionDao phoneSectionDao;// 号段
    
    @Autowired
    ProviderGroupBillRelDao providerGroupBillRelDao;// 运营商组
    
    @Autowired
    BillPkgDao billPkgDao;// 产品
    
    @Autowired
    AgentAccountDao agentAccountDao;// 代理商余额
    
    @Autowired
    AgentAccountChargeDao agentAccountChargeDao;
    
    @Autowired
    AgentBillDiscountDao agentBillDiscountDao;// 代理商话费折扣
    
    @Autowired
    ProviderBillDiscountDao providerBillDiscountDao;// 运营商折扣
    
    @Autowired
    ProviderBillDispatcherDao providerBillDispatcherDao;// 运营商分销商关联表
    
    @Autowired
    ProviderPhysicalChannelDao providerPhysicalChannelDao;// 通道的物理参数表
    
    @Autowired
    BaseBillDiscountDetailDao baseBillDiscountDetailDao;// 话费折扣模板
    
    @Autowired
    ProviderBillRechargeGroupDao providerRechargeGroupDao;// 复充通道组
    
    @Autowired
    OrderDao orderDao;// 订单表
    
    @Autowired
    RabbitMqProducer rabbitMqProducer;// 消息队列生产者
    
    /**
     * 查询订单状态
     * 
     * @author lks 2016年12月19日上午9:29:08
     * @param request
     * @return
     */
    public String queryOrder(HttpServletRequest request)
    {
        Map<String, Object> param = getMaps(request);
        String agentName = (String)param.get("terminalName");// 客户名
        String agentOrderId = (String)param.get("customerOrderId");// 客户订单号
        String orderType = (String)param.get("orderType");// 业务操作类型
        Map<String, Object> agent = agentDao.selectByAgentNameForOrder(agentName);
        String agentId = (String)agent.get("id");// 代理商ID
        Map<String, Object> queryParam = new HashMap<String, Object>();
        queryParam.put("agentId", agentId);
        queryParam.put("agentOrderId", agentOrderId);
        List<Map<String, Object>> orders = orderDao.selectAll(queryParam);
        Map<String, Object> order = orders.get(0);
        String status = (String)order.get("status");// 订单状态
        JSONObject json = new JSONObject();
        json.put("code", 0);
        json.put("message", "success");
        JSONObject data = new JSONObject();
        data.put("orderId", order.get("orderId"));
        data.put("customerOrderId", agentOrderId);
        data.put("mobile", order.get("phone"));
        data.put("basePrice", order.get("fee"));
        data.put("actualPrice", "");// TODO 折扣价
        if (status.equals("3"))
        {
            status = "0";
        }
        else if (status.equals("1"))
        {
            status = "1";
        }
        else if (status.equals("2") || status.equals("4"))
        {
            status = "2";
        }
        data.put("status", status);
        json.put("data", data);
        return json.toJSONString();
    }
    
    /**
     * 提交订单
     * 
     * @author lks 2016年12月6日上午10:02:04
     * @param request
     * @return
     */
    public String submitOrder(HttpServletRequest request)
    {
        int code = -1;
        Map<String, Object> param = getMaps(request);
        if (MapUtils.checkEmptyValue(param) && checkParamIntact(param))
        {
            code = createOrder(param);
        }
        else
        {
            code = 1;// 参数不全
        }
        JSONObject json = new JSONObject();
        String message = "";
        switch (code)
        {
            case 0:
                message = "提交成功";
                break;
            case 1:
                message = "参数不全";
                break;
            case 2:
                message = "签名错误";
                break;
            case 3:
                message = "该代理商不可用";
                break;
            case 4:
                message = "不支持该手机号段";
                break;
            case 5:
                message = "不允许充值该运营商号段，请联系业务人员获取权限";
                break;
            case 6:
                message = "无法充值该产品";
                break;
            case 7:
                message = "余额不足";
                break;
            case 8:
                message = "订单提交出现异常";
                break;
            default:
                code = -1;
                message = "状态返回值异常";
                break;
        }
        json.put("code", code);
        json.put("message", message);
        return json.toJSONString();
    }
    
    /**
     * 创建订单
     * 
     * @author lks 2016年12月6日下午1:48:42
     * @param param
     * @return
     */
    public int createOrder(Map<String, Object> param)
    {
        try
        {
            // 从参数map中获取参数
            String agentName = (String)param.get("terminalName");// 代理商名称
            String agentOrderId = (String)param.get("customerOrderId");// 下家订单号
            String price = (String)param.get("spec");// 充值金额
            String phoneNo = (String)param.get("phoneNo");// 手机号
            // 获取手机号相关信息
            String section = (phoneNo.length() == 13) ? phoneNo.substring(0, 5) : phoneNo.substring(0, 7);// 获取号段
            // TODO 号段从缓存中获取
            Map<String, Object> sectionMap = phoneSectionDao.selectBySection(section);
            if (sectionMap == null)
            {
                return 4;// 不支持该手机号段
            }
            String providerId = (String)sectionMap.get("provider_id");// 运营商ID
            param.put("providerId", providerId);
            String provinceCode = (String)sectionMap.get("province_code");// 省份代码
            String cityCode = (String)sectionMap.get("city_code");// 城市代码
            // 获取代理商对象
            Map<String, Object> agent = agentDao.selectByAgentNameForOrder(agentName);
            boolean agentFlag = true;// 声明接收的flag
            if (!checkAgent(agentFlag, agent))
            {
                return 3;// 该客户不可用
            }
            // 判断该代理商是否可用
            String agentId = (String)agent.get("id");// 代理商id
            param.put("agentId", agentId);
            String billGroupId = (String)agent.get("bill_group_id");// 话费运营商组Id
            if (!checkProviderForAgent(billGroupId, providerId))
            {
                return 5;// 不允许充值该运营商号段，请联系业务人员获取权限
            }
            Map<String, Object> billPkg = getBillPkgForAgent(providerId, price);
            if (billPkg == null)
            {
                return 6;// 无法充值该产品
            }
            if (!checkBalance4Agent(agentId, price))
            {
                // TODO 缓存余额不足的订单
                return 7;// 余额不足
            }
            // 获取扣款list
            List<Map<String, Object>> moneyList = new ArrayList<Map<String, Object>>();
            String billPkgId = (String)billPkg.get("id");
            moneyList = getChargeList(moneyList, agent, billPkgId, providerId, provinceCode, cityCode);
            if (moneyList.size() < 1)
            {
                log.error("扣款数据为空，订单号为" + agentOrderId);
                return 8;// 订单提交出现异常
            }
            // 生成订单对象
            Map<String, Object> order = getOrderObj(param);// 获取订单对象
            int orderCount = orderDao.insertSelective(order);// 保存订单对象
            order.put("billPkgId", billPkgId);// 将产品Id放入order对象，为了上家扣款
            order.put("provinceCode", provinceCode);// 省份代码，为了上家扣款
            order.put("cityCode", cityCode);// //城市代码，为了上家扣款
            if (orderCount != 1)
            {
                // TODO 异常订单自动处理
                log.error("订单插入数据库失败，订单号为" + agentOrderId);
                return 8;// 订单提交出现异常
            }
            Map<String, Object> msgMap = new HashMap<String, Object>();// 消息对象
            msgMap.put("order", order);
            msgMap.put("moneyList", moneyList);// 扣款的list
            // 将请求提交至扣款的消息队列
            rabbitMqProducer.sendDataToQueue(RabbitMqProducer.Money_QueueKey, SerializeUtil.getStrFromObj(msgMap));
        }
        catch (Exception e)
        {
            log.error("订单接收出现异常，异常为》》》" + e);
            getMyLog(e, log);
            return 8;// 订单提交出现异常
        }
        return 0;
    }
    
    /**
     * 订单处理方法
     * 
     * @author lks 2016年12月9日上午9:30:29
     * @param order 订单对象
     */
    public void dealOrder(Map<String, Object> order)
    {
        try
        {
            String providerId = (String)order.get("providerId");// 运营商Id
            // 获取分销商的id和权重
            List<Map<String, Object>> dpList = providerBillDispatcherDao.selectDispatcherByProviderId(providerId);
            String dispatcherProviderId = weightDeal(dpList);// 获取权重处理后的分销商ID
            order.put("dispatcherProviderId", dispatcherProviderId);
            order.put("dealCount", 1);// 处理次数
            orderDao.updateByPrimaryKeySelective(order);
            List<String> alreadyDealList = new ArrayList<String>();
            alreadyDealList.add(dispatcherProviderId);
            order.put("alreadyDealList", alreadyDealList);
            // 将确定好通道的订单加到队列中去处理
            Map<String, Object> physicalChannel = providerPhysicalChannelDao.selectByProviderId(dispatcherProviderId);
            // String queueName = (String) physicalChannel.get("queue_name");//队列名
            String providerMark = (String)physicalChannel.get("provider_mark");// 上家的唯一标识
            order.put("providerMark", providerMark);// 将上家的唯一标识加入order对象
            // 将订单对象放到通道处理队列
            rabbitMqProducer.sendDataToQueue(RabbitMqProducer.Channel_QueueKey, SerializeUtil.getStrFromObj(order));
        }
        catch (Exception e)
        {
            log.error("处理订单的逻辑出错" + e);
            getMyLog(e, log);
        }
    }
    
    /**
     * 权重处理，获取权重处理后的分销商ID
     * 
     * @author lks 2016年12月9日上午11:24:02
     * @param dpList
     * @return
     */
    public String weightDeal(List<Map<String, Object>> dpList)
    {
        // 权重处理
        String dispatcherProviderId = "";
        int weightSum = 0;// 权重总数
        for (int i = 0, size = dpList.size(); i < size; i++)
        {
            Map<String, Object> map = dpList.get(i);
            weightSum += Integer.parseInt((String)map.get("weight"));
        }
        if (weightSum <= 0)
        {
            log.error("权重设置出错");
        }
        Random random = new Random();
        int randomNum = random.nextInt(weightSum);// randomNum in [0,weightSum]
        int x = 0;
        for (int i = 0, size = dpList.size(); i < size; i++)
        {
            Map<String, Object> map = dpList.get(i);
            int weight = Integer.parseInt((String)map.get("weight"));// 权重
            if (x <= randomNum && randomNum < x + weight)
            {
                dispatcherProviderId = (String)map.get("dispatcher_provider_id");
                break;
            }
            x += randomNum;
        }
        return dispatcherProviderId;
    }
    
    /**
     * 复充方法
     * 
     * @author lks 2016年12月13日上午10:31:54
     * @param order
     */
    public void ReCharge(Map<String, Object> order)
    {
        @SuppressWarnings("unchecked")
        List<String> alreadyDealList = (List<String>)order.get("alreadyDealList");
        String providerId = (String)order.get("providerId");// 获取运营商ID
        String rechargeProviderId = getRechargeProviderId(alreadyDealList, providerId);// 获取要复充的运营商ID
        if (rechargeProviderId != null && !rechargeProviderId.equals(""))
        {// 复充运营商ID不为空
            alreadyDealList.add(rechargeProviderId);
            order.put("alreadyDealList", alreadyDealList);
            order.put("dispatcherProviderId", rechargeProviderId);
            int dealCount = (int)order.get("dealCount");// 处理次数
            order.put("dealCount", dealCount + 1);
            orderDao.updateByPrimaryKeySelective(order);
            // 将确定好通道的订单加到队列中去处理
            Map<String, Object> physicalChannel = providerPhysicalChannelDao.selectByProviderId(rechargeProviderId);
            // /String queueName = (String) physicalChannel.get("queue_name");//队列名
            String providerMark = (String)physicalChannel.get("provider_mark");// 上家的唯一标识
            order.put("providerMark", providerMark);// 将上家的唯一标识加入order对象
            // 将订单对象放到通道处理队列
            rabbitMqProducer.sendDataToQueue(RabbitMqProducer.Channel_QueueKey, SerializeUtil.getStrFromObj(order));
        }
        else
        {// 无复充通道可走
            boolean flag = dealOrderFail(order);
            if (flag)
            {
                log.debug("订单置为失败成功");
                Map<String, Object> callbackMap = new HashMap<String, Object>();
                callbackMap.put("status", "fail");
                callbackMap.put("order", order);
                rabbitMqProducer.sendDataToQueue(RabbitMqProducer.Callback_QueueKey,
                    SerializeUtil.getStrFromObj(callbackMap));
            }
            else
            {
                log.error("订单置为失败失败");
            }
        }
    }
    
    /**
     * 订单处理失败的处理方法
     * 
     * @author lks 2016年12月16日下午1:48:17
     * @param order
     */
    @Transactional
    public boolean dealOrderFail(Map<String, Object> order)
    {
        boolean flag = true;
        try
        {
            String agentId = (String)order.get("agentId");// 代理商ID
            order.put("status", 4);// 失败
            order.put("endDate", new Timestamp(System.currentTimeMillis()));
            int orderCount = orderDao.updateByPrimaryKeySelective(order);
            if (orderCount == 1)
            {
                List<Map<String, Object>> moneyList = new ArrayList<Map<String, Object>>();
                Map<String, Object> agent = agentDao.selectByPrimaryKeyForOrder(agentId);
                String billPkgId = (String)order.get("billPkgId");// 产品ID
                String providerId = (String)order.get("providerId");// 运营商ID
                String provinceCode = (String)order.get("provinceCode");// 省份
                String cityCode = (String)order.get("cityCode");// 城市
                moneyList = getChargeList(moneyList, agent, billPkgId, providerId, provinceCode, cityCode);
                for (int i = 0, size = moneyList.size(); i < size; i++)
                {
                    Map<String, Object> moneyMap = moneyList.get(i);
                    double money = -Double.parseDouble(moneyMap.get("money") + "");
                    moneyMap.put("money", money);
                    int chargeCount = agentAccountDao.charge(moneyMap);
                    if (chargeCount != 1)
                    {
                        flag = false;
                        log.error("订单置为失败，为代理商退款出错" + MapUtils.toString(order));
                    }
                    else
                    {
                        double beforeBalance = agentAccountDao.selectBalanceByAgentid(agentId);
                        double afterBalance = beforeBalance - money;// 扣除当前钱数之后的余额
                        Map<String, Object> aacMap = new HashMap<String, Object>();
                        String id = UUID.randomUUID().toString().replace("-", "");// 生成id
                        aacMap.put("id", id);
                        aacMap.put("agentId", agentId);
                        aacMap.put("orderId", order.get("orderId"));
                        aacMap.put("fee", money);
                        aacMap.put("balanceBefore", beforeBalance);
                        aacMap.put("balanceAfter", afterBalance);
                        aacMap.put("applyDate", new Timestamp(System.currentTimeMillis()));
                        int aacFlag = agentAccountChargeDao.insertSelective(aacMap);// 插入扣款记录表
                        if (aacFlag != 1)
                        {
                            log.error("扣款记录表未插入成功");
                        }
                    }
                }
            }
            else
            {
                flag = false;
                log.error("订单置为失败出错" + MapUtils.toString(order));
            }
        }
        catch (Exception e)
        {
            flag = false;
            log.error("订单置为失败出错" + e + "||||" + MapUtils.toString(order));
            getMyLog(e, log);
        }
        return flag;
    }
    
    /**
     * 获取要复充的运营商ID
     * 
     * @author lks 2016年12月15日下午3:48:44
     * @param order
     * @return
     */
    public String getRechargeProviderId(List<String> alreadyDealList, String providerId)
    {
        String rechargeId = "";
        // TODO
        List<Map<String, Object>> rechargeList = providerRechargeGroupDao.selectByProviderId(providerId);
        if (rechargeList != null)
        {
            for (int i = 0, size = alreadyDealList.size(); i < size; i++)
            {
                String alreadyDealId = alreadyDealList.get(i);// 已经充值过的ID
                for (int j = 0, Size = rechargeList.size(); j < Size; j++)
                {
                    Map<String, Object> dispatcherProviderMap = rechargeList.get(j);// 分销商ID
                    if (alreadyDealId.equals(dispatcherProviderMap.get("provider_physical_channel_id") + ""))
                    {
                        rechargeList.remove(j);
                        Size--;
                    }
                }
            }
        }
        if (rechargeList.size() > 0)
        {
            rechargeId = rechargeList.get(0).get("provider_physical_channel_id") + "";
        }
        return rechargeId;
    }
    
    /**
     * 判断参数是否完整
     * 
     * @author lks 2016年12月26日下午2:03:36
     * @param param
     * @return
     */
    public boolean checkParamIntact(Map<String, Object> param)
    {
        boolean flag = true;
        if (param.get("terminalName") == null || param.get("customerOrderId") == null || param.get("phoneNo") == null
            || param.get("orderType") == null || param.get("orderType") == null || param.get("spec") == null
            || param.get("scope") == null || param.get("callbackUrl") == null || param.get("timeStamp") == null
            || param.get("signature") == null)
        {
            flag = false;
        }
        return flag;
    }
    
    /**
     * 判断代理商是否可用
     * 
     * @author lks 2016年12月7日下午4:14:34
     * @param flag 接收状态 ，agent 代理商对象
     * @return
     */
    public boolean checkAgent(boolean flag, Map<String, Object> agent)
    {
        if (agent != null)
        {
            String status = (String)agent.get("status");// 获取状态
            if (!status.equals("1"))
            {
                flag = false;
            }
            String parentId = (String)agent.get("parent_id");// 获取父级Id
            if (!parentId.equals("0"))
            {// 0代表最高级
                Map<String, Object> parentAgent = agentDao.selectByPrimaryKeyForOrder(parentId);// 获取父级代理商
                flag = checkAgent(flag, parentAgent);
            }
        }
        else
        {
            flag = false;
        }
        return flag;
    }
    
    /**
     * 判断该代理商是否能充值该运营商号码
     * 
     * @author lks 2016年12月6日下午3:28:39
     * @param billGroupId 运营商组ID
     * @param providerId 运营商ID
     * @return true 可以充值，false 不可以充值
     */
    public boolean checkProviderForAgent(String billGroupId, String providerId)
    {
        Map<String, String> param = new HashMap<String, String>();
        param.put("billGroupId", billGroupId);
        param.put("providerId", providerId);
        int count = providerGroupBillRelDao.countByBillGroupIdAndProviderId(param);
        return count > 0 ? true : false;
    }
    
    /**
     * 获取代理商可以充值的产品
     * 
     * @author lks 2016年12月6日下午4:30:03
     * @param providerId 运营商id
     * @param price 充值金额
     * @return billPkg对象
     */
    public Map<String, Object> getBillPkgForAgent(String providerId, String price)
    {
        Map<String, String> param = new HashMap<String, String>();
        param.put("providerId", providerId);
        param.put("price", Double.parseDouble(price) / 100 + "");
        Map<String, Object> billPkg = billPkgDao.selectBillPkgForAgent(param);
        return billPkg;
    }
    
    /**
     * 判断代理商余额是否充足
     * 
     * @author lks 2016年12月6日下午4:41:56
     * @param agentId 代理商id
     * @param price 充值金额
     * @return true 余额充足，false 余额不足
     */
    public boolean checkBalance4Agent(String agentId, String price)
    {
        double balance = agentAccountDao.selectBalanceByAgentid(agentId) * 100;
        // TODO 资金预警
        return balance > Double.parseDouble(price) ? true : false;
    }
    
    /**
     * 获取订单对象
     * 
     * @author lks 2016年12月8日上午9:28:03
     * @param param
     * @return
     */
    public Map<String, Object> getOrderObj(Map<String, Object> param)
    {
        Map<String, Object> order = new HashMap<String, Object>();
        String id = UUID.randomUUID().toString().replace("-", "");// 生成id
        String agentOrderId = (String)param.get("customerOrderId");// 下家订单号
        String agentId = (String)param.get("agentId");// 代理商Id
        String providerId = (String)param.get("providerId");// 运营商Id
        String phone = (String)param.get("phoneNo");// 手机号
        String bizType = (String)param.get("orderType");// 业务类型 2 话费 1 流量
        double fee = Double.parseDouble((String)param.get("spec"));// 费用 分为单位
        String callbcakUrl = (String)param.get("callbackUrl");// 回调地址
        Timestamp applyDate = DateTimeUtils.getOrderTimestamp((String)param.get("timeStamp"));// 时间戳，格式：yyyyMMddHHmmssSSS
        order.put("id", id);
        order.put("agentOrderId", agentOrderId);
        order.put("agentId", agentId);
        order.put("providerId", providerId);
        order.put("phone", phone);
        order.put("bizType", bizType);
        if (bizType.equals("1"))
        {// 流量订单
            order.put("value", fee);
        }
        else if (bizType.equals("2"))
        {// 话费订单
            order.put("fee", fee / 100);
        }
        order.put("callbackUrl", callbcakUrl);
        order.put("callbackStatus", "0");
        order.put("applyDate", applyDate);
        // order.put("status", "0");//订单处理中状态
        return order;
    }
    
    /**
     * 获取分销商的折扣
     * 
     * @author lks 2016年12月9日上午9:46:55
     * @param providerId 运营商Id
     * @param billPkgId 产品ID
     * @param provinceCode 省份
     * @param cityCode 城市
     * @return
     */
    public double getProviderDiscount(String providerId, String billPkgId, String provinceCode, String cityCode)
    {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("providerId", providerId);
        param.put("billPkgId", billPkgId);
        param.put("provinceCode", provinceCode);
        param.put("cityCode", cityCode);
        double discount = providerBillDiscountDao.selectDiscount(param);// 获取该产品的运营商折扣
        return discount;
    }
    
    /**
     * 递归获取代理商扣款数据
     * 
     * @author lks 2016年12月7日上午8:39:38
     * @param list 接收数据的List<Map<String,Object>>
     * @param agent 代理商对象
     * @param billPkgId 产品ID
     * @param providerId 运营商ID
     * @param provinceCode 省份
     * @param cityCode 城市
     * @return list<Map<String,Object>> map中包含agentId(代理商Id),money(应扣钱数)
     */
    public List<Map<String, Object>> getChargeList(List<Map<String, Object>> list, Map<String, Object> agent,
        String billPkgId, String providerId, String provinceCode, String cityCode)
    {
        if (agent != null)
        {
            String agentId = (String)agent.get("id");// 获取代理商id
            String parentId = (String)agent.get("parent_id");// 获取父id
            String billModelId = (String)agent.get("bill_model_id");// 获取折扣模板id
            Map<String, String> param = new HashMap<String, String>();
            param.put("agentId", agentId);
            param.put("billPkgId", billPkgId);
            param.put("providerId", providerId);
            param.put("provinceCode", provinceCode);
            param.put("cityCode", cityCode);
            double discount = agentBillDiscountDao.selectDiscount(param);// 获取折扣
            if (discount == 0.0)
            {// 如果折扣获取不到，去折扣模板中去获取
                param.remove("agentId");
                param.put("billModelId", billModelId);
                discount = baseBillDiscountDetailDao.selectDiscount(param);
            }
            Map<String, Object> discountMap = new HashMap<String, Object>();
            discountMap.put("agentId", agentId);
            discountMap.put("money", discount);
            list.add(discountMap);
            if (!parentId.equals("0") && !parentId.trim().equals(""))
            {
                Map<String, Object> parentAgent = agentDao.selectByPrimaryKeyForOrder(parentId);
                getChargeList(list, parentAgent, billPkgId, providerId, provinceCode, cityCode);
            }
        }
        return list;
    }
    
}
